home *** CD-ROM | disk | FTP | other *** search
- //--------------------------------------------------------------------------
- //
- // Copyright (c) 2002, Colin Granville
- //
- // All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or
- // without modification, are permitted provided that the following
- // conditions are met:
- //
- // * Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- //
- // * Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following
- // disclaimer in the documentation and/or other materials
- // provided with the distribution.
- //
- // * The name Colin Granville may not be used to endorse or promote
- // products derived from this software without specific prior
- // written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- // OF THE POSSIBILITY OF SUCH DAMAGE.
- //
- //--------------------------------------------------------------------------
-
- #include <iostream.h>
- #include "GuiDrawFileRender.h"
- #include "DrawFileParser.h"
- #include "DrawFileVisitor.h"
-
- int mult(int a,int b) {return int(double(a)*double(b)/(1<<16));}
-
- void matrixMult(const DrawFileVisitor::Transform& a,
- const DrawFileVisitor::Transform& b,
- DrawFileVisitor::Transform& res)
- {
- res.m0=mult(a.m0,b.m0)+mult(a.m1,b.m2); res.m1=mult(a.m0,b.m1)+mult(a.m1,b.m3);
- res.m2=mult(a.m2,b.m0)+mult(a.m3,b.m2); res.m3=mult(a.m2,b.m1)+mult(a.m3,b.m3);
- res.m4=res.m5=0;
- }
-
- void transform(const DrawFileVisitor::Transform& m,int x,int y,int& xr,int& yr)
- {
- xr=mult(x,m.m0)+mult(y,m.m2)+m.m4;
- yr=mult(x,m.m1)+mult(y,m.m3)+m.m5;
- }
-
- class DrawParser: public DrawFileParser
- {
- public:
- DrawParser(const GuiDrawFile& d) : draw(d) {}
- virtual void* getObject(size_t start) const {return (void*)draw.getPtr(start);}
- virtual size_t getSize() const {return draw.getSize();}
- private:
- const GuiDrawFile& draw;
- };
-
- //**************************************************************************
- //**************************************************************************
- //**************************************************************************
-
- class Font
- {
- public:
- Font(DrawFileParser& parser);
- ~Font();
- void setTable(size_t start) {table=start;}
- void find(int number,size_t width,size_t height);
-
- private:
- DrawFileParser& parser;
- size_t table;
- int number;
- size_t width;
- size_t height;
- int handle;
- int nameoffset;
- };
-
- //**************************************************************************
-
- Font::Font(DrawFileParser& p)
- : parser(p),
- table(0),
- number(-1),
- handle(0),
- nameoffset(1)
- {
- }
-
- //**************************************************************************
-
- Font::~Font()
- {
- if (handle) _swix(Font_LoseFont,_IN(0),handle);
- }
-
- //**************************************************************************
-
- void Font::find(int n,size_t w,size_t h)
- {
- if (number==n && width==w && height==h) return;
-
- unsigned char* start=(unsigned char*)parser.getObject(table);
- unsigned char* p;
-
- unsigned char num;
- if (number==n)
- {
- p=start+nameoffset;
- num=number;
- }
- else
- {
- p=start;
- while (num=*p++,!(num==n || num==0))
- {
- while (*p!=0) p++;
- p++;
- }
- nameoffset=p-start;
- }
- int oldHandle=handle;
- int newHandle=0;
- if (num==0 || _swix(Font_FindFont,_INR(1,5)|_OUT(0),(char*)p,w/40,h/40,0,0,&newHandle))
- {
- _swix(Font_FindFont,_INR(1,5)|_OUT(0),"Trinity.Medium",w/40,h/40,0,0,&newHandle);
- }
-
- if (newHandle)
- {
- if (oldHandle) _swix(Font_LoseFont,_IN(0),oldHandle);
- handle=newHandle;
- number=n;
- width =w;
- height=h;
- }
- }
-
- //**************************************************************************
- //**************************************************************************
- //**************************************************************************
-
-
- //**************************************************************************
-
- class Renderer : public DrawFileVisitor
- {
- public:
- Renderer(DrawFileParser& parser,
- const DrawFileVisitor::Transform& t,
- const GuiBBox& clipBox,
- bool toPrinter);
- ~Renderer();
-
- private:
- DrawFileParser& parser;
- const Transform& matrix;
- GuiBBox clipBox;
- Font font;
- unsigned int blendFont;
-
- virtual int fontTable(size_t start);
- virtual int transformedTextObject(size_t start);
- virtual int transformedSpriteObject(size_t start);
- virtual int pathObject(size_t start);
-
- };
-
- //**************************************************************************
- class Convert
- {
- public:
- Convert(double* matrix) : ctm(matrix) {}
-
- void convert(double x1, double y1, int& x2, int& y2)
- {
- x2 = (int)(ctm[0] * x1 + ctm[2] * y1);
- y2 = (int)(ctm[1] * x1 + ctm[3] * y1);
- }
- private:
- double* ctm;
- };
-
- inline void set(GuiBBox& b,int x,int y)
- {
- if (x<b.xmin) b.xmin=x;
- if (x>b.xmax) b.xmax=x;
- if (y<b.ymin) b.ymin=y;
- if (y>b.ymax) b.ymax=y;
- }
-
- Renderer::Renderer(DrawFileParser& p,
- const DrawFileVisitor::Transform& t,
- const GuiBBox& c,
- bool blend)
- : parser(p),
- matrix(t),
- font(p),
- blendFont(blend?(1<<11):0)
- {
-
- //transform bounding box using inverse matrix;
- double m[4], im[4];
- m[0]=((double)t.m0)/0x10000;
- m[1]=((double)t.m1)/0x10000;
- m[2]=((double)t.m2)/0x10000;
- m[3]=((double)t.m3)/0x10000;
- double det=1/(m[0]*m[3] - m[1]*m[2]);
- im[0]=m[3]*det;
- im[1]=-m[1]*det;
- im[2]=-m[2]*det;
- im[3]=m[0]*det;
-
- Convert cvt(im);
- int x,y;
- cvt.convert(double(c.xmin*256-t.m4) ,double(c.ymin*256-t.m5),x,y);
- clipBox.xmin=clipBox.xmax=x;
- clipBox.ymin=clipBox.ymax=y;
-
- cvt.convert(double(c.xmin*256-t.m4),double(c.ymax*256-t.m5),x,y);
- set(clipBox,x,y);
- cvt.convert(double(c.xmax*256-t.m4),double(c.ymax*256-t.m5),x,y);
- set(clipBox,x,y);
- cvt.convert(double(c.xmax*256-t.m4),double(c.ymin*256-t.m5),x,y);
- set(clipBox,x,y);
- };
-
- //**************************************************************************
-
- Renderer::~Renderer() {}
-
- //**************************************************************************
-
- int Renderer::fontTable(size_t start)
- {
- font.setTable(start+sizeof(DrawFileVisitor::FontTable));
-
- return 1;
- }
-
- //**************************************************************************
-
- int Renderer::transformedTextObject(size_t start)
- {
- DrawFileVisitor::TransformedTextObject& text=
- *(DrawFileVisitor::TransformedTextObject*)parser.getObject(start);
- if (!clipBox.overlap(text.bounds)) return 1;
-
- font.find(text.font,text.fontXSize,text.fontYSize);
- _swix(ColourTrans_SetFontColours,_INR(0,3),0,text.backColour,text.foreColour,14);
-
- DrawFileVisitor::Transform res;
- matrixMult(matrix,text.matrix,res);
- int x,y;
- transform(matrix,text.x,text.y,x,y);
-
- _swix(Font_Paint,_INR(0,7),0,text.getText(),(1<<6)|(1<<8)|blendFont,x*25/16,y*25/16,0,&res,0);
- return 1;
- }
-
- //**************************************************************************
-
- int Renderer::transformedSpriteObject(size_t start)
- {
- DrawFileVisitor::TransformedSpriteObject* sprite=
- (DrawFileVisitor::TransformedSpriteObject*)parser.getObject(start);
- if (!clipBox.overlap(sprite->bounds)) return 1;
- DrawFileVisitor::Transform res;
- matrixMult(matrix,sprite->matrix,res);
- transform(matrix,sprite->matrix.m4,sprite->matrix.m5,res.m4,res.m5);
-
- int i;
- int tableSize=0;
- char* table=0;
- for (i=0;i<2;i++)
- {
- sprite=(DrawFileVisitor::TransformedSpriteObject*)parser.getObject(start);
- _swix(ColourTrans_SelectTable,_INR(0,5)|_OUT(4),
- sprite->getSprite(),sprite->getSprite(),-1,-1,table,3|(1<<4),&tableSize);
- if (i==1 || tableSize==0) break;
-
- table=new char[tableSize];
- if (!table) break;
- }
-
- _swix(OS_SpriteOp,_INR(0,7),0x200+56,
- sprite->getSprite(),sprite->getSprite(),0,0,8 | (1<<5),&res,table);
- delete [] table;
- return 1;
- }
-
- //**************************************************************************
-
- int Renderer::pathObject(size_t start)
- {
- DrawFileVisitor::PathObject& path=*(DrawFileVisitor::PathObject*)parser.getObject(start);
- if (!clipBox.overlap(path.bounds)) return 1;
- if (path.fillColour != -1)
- {
- _swix(ColourTrans_SetGCOL,_IN(0)|_INR(3,4),path.fillColour,0x100,0);
- // size_t s=sizeof(DrawFileVisitor::PathObject);
- // _swix(Draw_Fill,_INR(0,3),path.pathStart(),((path.pathStyle & (1<<6))?0x32:0x30),&matrix,0);
- _swix(Draw_Fill,_INR(0,3),path.pathStart(),
- ((path.pathStyle & (1<<6))?0x32:0)/*0x3a:0x38)*/,&matrix,0);
-
- if (path.outlineColour == -1 && blendFont)
- {
- // bodge to display areas which disappear on screen
- // only do this for screen rendering
- // blendFont <> 0 if drawing to screen
- struct
- {
- unsigned int style;
- int mitreJoin;
- unsigned int leadCap;
- unsigned int trailCap;
- } capAndJoin;
- capAndJoin.style=0x00010101;
- capAndJoin.mitreJoin=0;
- capAndJoin.leadCap=0;
- capAndJoin.trailCap=capAndJoin.leadCap;
- _swix(Draw_Stroke,_INR(0,6),path.pathStart(),0,&matrix,0,0,&capAndJoin,0);
- }
- }
-
- if (path.outlineColour != -1)
- {
- _swix(ColourTrans_SetGCOL,_IN(0)|_INR(3,4),path.outlineColour,0x100,0);
- struct
- {
- unsigned int style;
- int mitreJoin;
- unsigned int leadCap;
- unsigned int trailCap;
- } capAndJoin;
-
- capAndJoin.style= ( (path.pathStyle & 3) |
- (((path.pathStyle>>4) & 3)<<8) |
- (((path.pathStyle>>2) & 3)<<16) );
- capAndJoin.leadCap=( (path.capWidth*16) | ((path.capHeight*16)<<16) );
- capAndJoin.trailCap=capAndJoin.leadCap;
- // capAndJoin.mitreJoin=((path.outlineWidth*4)<<8);
- capAndJoin.mitreJoin=8<<16;
- _swix(Draw_Stroke,_INR(0,6),path.pathStart(),0x38,&matrix,0,
- path.outlineWidth,&capAndJoin,
- path.dashStart());
- }
-
-
- return 1;
- }
-
- //**************************************************************************
- //**************************************************************************
- //**************************************************************************
-
-
- _kernel_oserror* GuiDrawFile_render(const GuiDrawFile& draw,
- const DrawFileVisitor::Transform* mat,
- const GuiBBox* clipBox,
- bool blendFonts)
- {
- static GuiBBox defClipBox={0,0,0x7fff,0x7fff};
- static DrawFileVisitor::Transform defMatrix={(1<<16),0,0,(1<<16),0,0};
-
- DrawParser drawfile(draw);
- Renderer renderer(drawfile,
- *(mat?mat:&defMatrix),
- *(clipBox?clipBox:&defClipBox),
- blendFonts);
- drawfile.accept(renderer);
- //DrawFile_Render
- //return _swix(0x45540,_INR(0,5),0,draw.getPtr(0),size,
- // (mat?mat:&defMatrix),(clipBox?clipBox:&defClipBox),0);
- return 0;
- };
-